package com.zf.unsafe;

import lombok.Getter;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * Unsafe类的使用
 */
@Getter
public class UnSafeTest {

    private String name;


    public static void main(String[] args) throws NoSuchFieldException {
        UnSafeTest ut = new UnSafeTest();
        System.out.println(ut.getName());

        // 获取Unsafe类
        Unsafe unsafe = getUnsafe();

        // 类的某个属性
        Field nameField = UnSafeTest.class.getDeclaredField("name");
        // 属性偏移位置
        long nameFieldOffset = unsafe.objectFieldOffset(nameField);

        // 给对象的属性设置值
        // 直接设置
        unsafe.putObject(ut, nameFieldOffset, "李四");
        System.out.println(ut.getName());
        System.out.println(unsafe.getObject(ut, nameFieldOffset));

        unsafe.putObject(ut, nameFieldOffset, null);
        System.out.println(ut.getName());
        System.out.println(unsafe.getObject(ut, nameFieldOffset));


        // 比较并设置
        boolean swapRes1 = unsafe.compareAndSwapObject(ut, nameFieldOffset, ut.getName(), "王五");
        System.out.println(ut.getName());
        System.out.println(unsafe.getObject(ut, nameFieldOffset));

        boolean swapRes2 = unsafe.compareAndSwapObject(ut, nameFieldOffset, ut.getName(), "赵六");
        System.out.println(ut.getName());
        System.out.println(unsafe.getObject(ut, nameFieldOffset));
    }


    /**
     * 反射获取 Unsafe 实例
     */
    public static Unsafe getUnsafe() {
        try {
            // 获取 Unsafe 类中的 theUnsafe 字段
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            // 设置字段可访问
            field.setAccessible(true);
            // 获取 Unsafe 实例
            return (Unsafe) field.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
